import socket
import json
import threading
import time
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
from datetime import datetime
import logging

# 配置日志，添加日期时间格式
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    """多线程HTTP服务器"""
    pass

class TCPServer:
    """TCP服务器，监听6667端口，转发UDP广播数据"""
    
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.server_socket = None
        self.clients = set()
        self.running = False
        self.heartbeat_thread = None
    
    def start(self):
        """启动TCP服务器"""
        try:
            self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server_socket.bind((self.host, self.port))
            self.server_socket.listen(5)
            self.running = True
            
            logging.info(f"TCP服务器已启动，监听 {self.host}:{self.port}")
            
            # 启动心跳线程
            self.heartbeat_thread = threading.Thread(target=self._send_heartbeat)
            self.heartbeat_thread.daemon = True
            self.heartbeat_thread.start()
            
            # 接受客户端连接
            while self.running:
                client_socket, client_address = self.server_socket.accept()
                logging.info(f"新客户端连接: {client_address}")
                self.clients.add(client_socket)
                
                # 为每个客户端创建接收线程
                client_thread = threading.Thread(target=self._handle_client, args=(client_socket,))
                client_thread.daemon = True
                client_thread.start()
                
        except Exception as e:
            logging.error(f"TCP服务器启动失败: {e}")
        finally:
            self.stop()
    
    def stop(self):
        """停止TCP服务器"""
        self.running = False
        if self.server_socket:
            self.server_socket.close()
        for client in self.clients:
            client.close()
        self.clients.clear()
        logging.info("TCP服务器已停止")
    
    def _handle_client(self, client_socket):
        """处理客户端连接"""
        try:
            while self.running:
                # 这里只是保持连接，不主动接收客户端数据
                # 实际应用中可能需要根据需求接收客户端数据
                time.sleep(1)
        except Exception as e:
            logging.error(f"客户端连接错误: {e}")
        finally:
            if client_socket in self.clients:
                self.clients.remove(client_socket)
            client_socket.close()
    
    def _send_heartbeat(self):
        """发送心跳包"""
        while self.running:
            try:
                heartbeat_msg = json.dumps({"eventType": "HEARTBEAT", "data": "pong"}) + "\r\n"
                heartbeat_data = heartbeat_msg.encode('utf-8')
                
                # 向所有客户端发送心跳包
                for client in list(self.clients):
                    try:
                        client.sendall(heartbeat_data)
                    except:
                        # 移除断开的客户端
                        if client in self.clients:
                            self.clients.remove(client)
                        client.close()
                
                logging.debug("发送心跳包")
                time.sleep(10)  # 每10秒发送一次心跳
            except Exception as e:
                logging.error(f"发送心跳包时出错: {e}")
    
    def send_event(self, event_type, data):
        """向所有客户端发送事件"""
        try:
            event_msg = json.dumps({"eventType": event_type, "data": data}) + "\r\n"
            event_data = event_msg.encode('utf-8')
            
            logging.info(f"发送事件: {event_type}")
            
            for client in list(self.clients):
                try:
                    client.sendall(event_data)
                except:
                    if client in self.clients:
                        self.clients.remove(client)
                    client.close()
        except Exception as e:
            logging.error(f"发送事件时出错: {e}")

class HTTPRequestHandler(BaseHTTPRequestHandler):
    """HTTP请求处理程序"""
    
    # 禁用默认的日志输出
    def log_message(self, format, *args):
        return
    
    def _send_response(self, data):
        """发送JSON响应"""
        response = json.dumps(data).encode('utf-8')
        self.send_response(200)
        self.send_header('Content-Type', 'application/json')
        self.send_header('Content-Length', len(response))
        self.end_headers()
        self.wfile.write(response)
    
    def do_POST(self):
        """处理POST请求"""
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        
        try:
            request_data = json.loads(post_data.decode('utf-8'))
            logging.info(f"收到请求: {self.path} - {request_data}")
            
            # 根据路径和action处理请求
            if self.path == "/api/faceRecognition":
                self._handle_face_recognition(request_data)
            elif self.path == "/api/faceEvent":
                self._handle_face_event(request_data)
            elif self.path == "/api/tts":
                self._handle_tts(request_data)
            elif self.path == "/api/ttsEvent":
                self._handle_tts_event(request_data)
            else:
                self._send_response({"code": 404, "message": "未找到接口", "success": False})
                
        except json.JSONDecodeError:
            self._send_response({"code": 400, "message": "无效的JSON格式", "success": False})
        except Exception as e:
            self._send_response({"code": 500, "message": f"服务器内部错误: {str(e)}", "success": False})
    
    def _handle_face_recognition(self, data):
        """处理人脸识别相关请求"""
        action = data.get("action")
        
        if action == "start_recognition":
            # 启动人脸识别
            self.server.face_service.start_recognition()
            self._send_response({"code": 200, "message": "人脸识别已启动", "success": True, "data": None})
            logging.info("处理请求: 启动人脸识别")
        
        elif action == "stop_recognition":
            # 停止人脸识别
            self.server.face_service.stop_recognition()
            self._send_response({"code": 200, "message": "人脸识别已停止", "success": True, "data": None})
            logging.info("处理请求: 停止人脸识别")
        
        elif action == "query_recognition":
            # 查询识别结果
            result = self.server.face_service.query_recognition(data.get("userIdType", "1"))
            self._send_response({"code": 200, "message": "查询成功", "success": True, "data": result})
            logging.info("处理请求: 查询识别结果")
        
        elif action == "query_faceInfo":
            # 获取人脸特征
            face_info = self.server.face_service.get_face_info(
                data.get("userId"), data.get("userIdType", "1"))
            self._send_response({"code": 200, "message": "获取成功", "success": True, "data": face_info})
            logging.info("处理请求: 查询人脸信息")
        
        else:
            self._send_response({"code": 400, "message": "无效的action", "success": False})
            logging.warning("处理请求: 无效的人脸识别action")
    
    def _handle_face_event(self, data):
        """处理人脸事件相关请求"""
        action = data.get("action")
        event_types = data.get("eventTypes", [])
        
        if action == "subscribe":
            # 订阅人脸事件
            for event_type in event_types:
                if event_type in ["FACE_RECOGNIZED"]:
                    self.server.face_service.subscribe_event(event_type, self.client_address)
            self._send_response({"code": 200, "message": "订阅成功", "success": True, "data": None})
            logging.info(f"处理请求: 订阅人脸事件 - {event_types}")
        
        elif action == "unsubscribe":
            # 取消订阅人脸事件
            for event_type in event_types:
                self.server.face_service.unsubscribe_event(event_type, self.client_address)
            self._send_response({"code": 200, "message": "取消订阅成功", "success": True, "data": None})
            logging.info(f"处理请求: 取消订阅人脸事件 - {event_types}")
        
        else:
            self._send_response({"code": 400, "message": "无效的action", "success": False})
            logging.warning("处理请求: 无效的人脸事件action")
    
    def _handle_tts(self, data):
        """处理语音合成相关请求"""
        action = data.get("action")
        
        if action == "add":
            # 添加语音到队列
            message = data.get("message")
            self.server.tts_service.add_to_queue(message)
            self._send_response({"code": 200, "message": "语音已加入队列", "success": True, "data": None})
            logging.info(f"处理请求: 添加语音到队列 - {message}")
        
        elif action == "flush":
            # 清空语音队列
            self.server.tts_service.flush_queue()
            self._send_response({"code": 200, "message": "队列已清空", "success": True, "data": None})
            logging.info("处理请求: 清空语音队列")
        
        elif action == "stop":
            # 停止当前语音
            self.server.tts_service.stop_speech()
            self._send_response({"code": 200, "message": "语音已停止", "success": True, "data": None})
            logging.info("处理请求: 停止当前语音")
        
        elif action == "restart":
            # 重新播报语音（新增功能）
            message = data.get("message")
            self.server.tts_service.restart_speech(message)
            self._send_response({"code": 200, "message": "语音已重新播报", "success": True, "data": None})
            logging.info(f"处理请求: 重新播报语音 - {message}")
        
        elif action == "query_queue_status":
            # 查询队列状态
            status = self.server.tts_service.get_queue_status()
            self._send_response({"code": 200, "message": "查询成功", "success": True, "data": status})
            logging.info("处理请求: 查询队列状态")
        
        else:
            self._send_response({"code": 400, "message": "无效的action", "success": False})
            logging.warning("处理请求: 无效的语音合成action")
    
    def _handle_tts_event(self, data):
        """处理语音事件相关请求"""
        action = data.get("action")
        event_types = data.get("eventTypes", [])
        
        if action == "subscribe":
            # 订阅语音事件
            for event_type in event_types:
                if event_type in ["SPEECH_STATUS_CHANGED"]:
                    self.server.tts_service.subscribe_event(event_type, self.client_address)
            self._send_response({"code": 200, "message": "订阅成功", "success": True, "data": None})
            logging.info(f"处理请求: 订阅语音事件 - {event_types}")
        
        elif action == "unsubscribe":
            # 取消订阅语音事件
            for event_type in event_types:
                self.server.tts_service.unsubscribe_event(event_type, self.client_address)
            self._send_response({"code": 200, "message": "取消订阅成功", "success": True, "data": None})
            logging.info(f"处理请求: 取消订阅语音事件 - {event_types}")
        
        else:
            self._send_response({"code": 400, "message": "无效的action", "success": False})
            logging.warning("处理请求: 无效的语音事件action")

class FaceRecognitionService:
    """人脸识别服务"""
    
    def __init__(self, tcp_server):
        self.tcp_server = tcp_server
        self.running = False
        self.subscribers = {"FACE_RECOGNIZED": set()}
        # 修改数据结构，将ID作为键，包含姓名和人脸特征
        self.demo_data = {
            "12345": {"name": "张三", "face_feature": "base64编码的人脸特征1"},
            "56789": {"name": "李四", "face_feature": "base64编码的人脸特征2"}
        }
        
        # 启动模拟人脸识别线程
        self.thread = threading.Thread(target=self._simulate_face_recognition)
        self.thread.daemon = True
        self.thread.start()
    
    def start_recognition(self):
        """启动人脸识别"""
        self.running = True
        logging.info("人脸识别已启动")
    
    def stop_recognition(self):
        """停止人脸识别"""
        self.running = False
        logging.info("人脸识别已停止")
    
    def query_recognition(self, user_id_type):
        """查询识别结果：返回姓名和ID"""
        if not self.running:
            return {"name": "未识别", "id": ""}
        
        # 随机返回一个识别结果
        if user_id_type == "1":  # 身份证类型
            user_id = list(self.demo_data.keys())[0]
            return {"name": self.demo_data[user_id]["name"], "id": user_id}
        return {"name": "未知用户", "id": ""}
    
    def get_face_info(self, user_id, user_id_type):
        """获取人脸信息：返回人脸特征（修复）"""
        if user_id in self.demo_data:
            # 修复：返回人脸特征，而非姓名和ID
            return {"face": self.demo_data[user_id]["face_feature"]}
        return {"face": "未找到人脸特征"}
    
    def subscribe_event(self, event_type, client_address):
        """订阅人脸事件"""
        if event_type in self.subscribers:
            self.subscribers[event_type].add(client_address)
            logging.info(f"客户端 {client_address} 订阅了 {event_type} 事件")
    
    def unsubscribe_event(self, event_type, client_address):
        """取消订阅人脸事件"""
        if event_type in self.subscribers and client_address in self.subscribers[event_type]:
            self.subscribers[event_type].remove(client_address)
            logging.info(f"客户端 {client_address} 取消订阅了 {event_type} 事件")
    
    def _simulate_face_recognition(self):
        """模拟人脸识别过程"""
        while True:
            if self.running:
                # 每10秒模拟识别到一个人脸
                time.sleep(10)
                user_id = list(self.demo_data.keys())[0]
                user_info = self.demo_data[user_id]
                
                # 构建人脸识别人脸事件（包含ID和姓名）
                event_data = {
                    "name": user_info["name"],
                    "id": user_id,
                    "timestamp": datetime.now().isoformat() + "Z"
                }
                
                # 发送事件到TCP客户端
                self.tcp_server.send_event("FACE_RECOGNIZED", event_data)
                
                # 发送事件到HTTP订阅者（实际应用中可能需要不同的实现）
                # 这里简化处理，通过TCP服务器发送
            else:
                time.sleep(1)

class TTSService:
    """语音合成服务"""
    
    def __init__(self, tcp_server):
        self.tcp_server = tcp_server
        self.queue = []
        self.current_text = ""
        self.status = "IDLE"  # IDLE, PLAYING
        self.subscribers = {"SPEECH_STATUS_CHANGED": set()}
        
        # 启动语音处理线程
        self.thread = threading.Thread(target=self._process_queue)
        self.thread.daemon = True
        self.thread.start()
    
    def add_to_queue(self, message):
        """添加语音到队列"""
        self.queue.append(message)
        logging.info(f"添加语音到队列: {message}")
    
    def flush_queue(self):
        """清空语音队列"""
        self.queue = []
        logging.info("已清空语音队列")
    
    def stop_speech(self):
        """停止当前语音"""
        self.status = "IDLE"
        self.current_text = ""
        logging.info("已停止当前语音")
        
        # 发送状态变更事件
        self._send_status_event("STOPPED", "")
    
    def restart_speech(self, message):
        """重新播报语音（清空队列+播放新内容）"""
        self.queue = []
        self.status = "PLAYING"
        self.current_text = message
        logging.info(f"重新播报语音: {message}")
        
        # 发送状态变更事件
        self._send_status_event("PLAYING", message)
    
    def get_queue_status(self):
        """查询队列状态"""
        return {
            "queueLength": len(self.queue),
            "currentPlayingText": self.current_text,
            "status": self.status
        }
    
    def subscribe_event(self, event_type, client_address):
        """订阅语音事件"""
        if event_type in self.subscribers:
            self.subscribers[event_type].add(client_address)
            logging.info(f"客户端 {client_address} 订阅了 {event_type} 事件")
    
    def unsubscribe_event(self, event_type, client_address):
        """取消订阅语音事件"""
        if event_type in self.subscribers and client_address in self.subscribers[event_type]:
            self.subscribers[event_type].remove(client_address)
            logging.info(f"客户端 {client_address} 取消订阅了 {event_type} 事件")
    
    def _process_queue(self):
        """处理语音队列"""
        while True:
            if self.status == "IDLE" and self.queue:
                # 从队列中取出下一条语音
                self.current_text = self.queue.pop(0)
                self.status = "PLAYING"
                
                # 发送状态变更事件
                self._send_status_event("PLAYING", self.current_text)
                
                logging.info(f"正在播放: {self.current_text}")
                
                # 模拟语音播放（3秒）
                time.sleep(3)
                
                # 播放完成
                self.status = "IDLE"
                self._send_status_event("FINISHED", self.current_text)
                self.current_text = ""
            else:
                time.sleep(1)
    
    def _send_status_event(self, status, text):
        """发送语音状态变更事件"""
        event_data = {
            "status": status,
            "text": text
        }
        
        # 发送事件到TCP客户端
        self.tcp_server.send_event("SPEECH_STATUS_CHANGED", event_data)

class ProtocolServer:
    """协议服务器，整合TCP和HTTP服务"""
    
    def __init__(self, host="0.0.0.0", tcp_port=6667, face_port=6688, tts_port=8866):
        self.host = host
        self.tcp_port = tcp_port
        self.face_port = face_port
        self.tts_port = tts_port
        
        # 创建TCP服务器
        self.tcp_server = TCPServer(host, tcp_port)
        
        # 创建HTTP服务器
        self.http_server = ThreadedHTTPServer((host, face_port), HTTPRequestHandler)
        self.http_server.face_service = FaceRecognitionService(self.tcp_server)
        self.http_server.tts_service = TTSService(self.tcp_server)
        
        # 创建语音服务HTTP服务器
        self.tts_http_server = ThreadedHTTPServer((host, tts_port), HTTPRequestHandler)
        self.tts_http_server.face_service = self.http_server.face_service
        self.tts_http_server.tts_service = self.http_server.tts_service
    
    def start(self):
        """启动服务器"""
        try:
            logging.info(f"启动协议服务器（V1.5），主机: {self.host}")
            
            # 启动TCP服务器（在单独线程中）
            tcp_thread = threading.Thread(target=self.tcp_server.start)
            tcp_thread.daemon = True
            tcp_thread.start()
            
            # 启动人脸识别HTTP服务器（在单独线程中）
            face_http_thread = threading.Thread(target=self.http_server.serve_forever)
            face_http_thread.daemon = True
            face_http_thread.start()
            
            # 启动语音合成HTTP服务器（在单独线程中）
            tts_http_thread = threading.Thread(target=self.tts_http_server.serve_forever)
            tts_http_thread.daemon = True
            tts_http_thread.start()
            
            logging.info(f"TCP服务器监听端口: {self.tcp_port}")
            logging.info(f"人脸识别HTTP服务器监听端口: {self.face_port}")
            logging.info(f"语音合成HTTP服务器监听端口: {self.tts_port}")
            
            logging.info("服务器已就绪，按Ctrl+C停止...")
            
            # 保持主线程运行
            while True:
                time.sleep(1)
                
        except KeyboardInterrupt:
            logging.info("\n接收到停止信号，正在关闭服务器...")
            self.stop()
        except Exception as e:
            logging.error(f"服务器启动失败: {e}")
            self.stop()
    
    def stop(self):
        """停止服务器"""
        self.tcp_server.stop()
        self.http_server.shutdown()
        self.tts_http_server.shutdown()
        logging.info("服务器已关闭")

if __name__ == "__main__":
    server = ProtocolServer()  # 默认监听所有网卡（0.0.0.0）
    # 若需指定特定IP，可改为 server = ProtocolServer(host="192.168.1.100")
    server.start()    

